package com.company.aicrawlers.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.company.aicrawlers.common.dto.PageResponse;
import com.company.aicrawlers.common.exception.BusinessException;
import com.company.aicrawlers.entity.Question;
import com.company.aicrawlers.mapper.QuestionMapper;
import com.company.aicrawlers.service.QuestionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 问句服务实现类
 *
 * @author AI Crawlers Team
 * @date 2025-10-10
 */
@Slf4j
@Service
public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> implements QuestionService {
    
    @Autowired
    private QuestionMapper questionMapper;
    
    @Autowired
    private com.company.aicrawlers.service.QuestionProductService questionProductService;
    
    @Autowired
    private com.company.aicrawlers.service.QuestionCategoryService questionCategoryService;
    
    @Override
    public PageResponse<Question> getPageList(Integer page, Integer size, String keyword, String category, Integer status) {
        // 构建分页对象
        Page<Question> pageParam = new Page<>(page, size);
        
        // 构建查询条件
        LambdaQueryWrapper<Question> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StrUtil.isNotBlank(keyword), Question::getQuestionContent, keyword)
                    .eq(StrUtil.isNotBlank(category), Question::getCategory, category)
                    .eq(status != null, Question::getStatus, status)
                    .orderByDesc(Question::getCreateTime);
        
        // 执行分页查询
        IPage<Question> pageResult = questionMapper.selectPage(pageParam, queryWrapper);
        
        // 封装返回结果
        return new PageResponse<>(
                pageResult.getTotal(),
                (int) pageResult.getCurrent(),
                (int) pageResult.getSize(),
                pageResult.getRecords()
        );
    }
    
    @Override
    public PageResponse<Question> getPageListEnhanced(Integer page, Integer size, String keyword, String category, 
                                                      Long productId, Long productCategoryId, Integer status) {
        // 先获取符合条件的问句ID列表
        List<Long> questionIds = new ArrayList<>();
        
        // 如果按产品筛选
        if (productId != null) {
            questionIds = questionProductService.getQuestionIdsByProductId(productId);
            if (questionIds.isEmpty()) {
                // 如果该产品没有关联任何问句，直接返回空结果
                return new PageResponse<>(0L, page, size, new ArrayList<>());
            }
        }
        
        // 如果按产品类别筛选
        if (productCategoryId != null) {
            // TODO: 需要通过category_id查询category_name，然后再查询问句
            // 暂时简化处理，后续优化
            List<Long> categoryQuestionIds = new ArrayList<>();
            if (questionIds.isEmpty()) {
                questionIds = categoryQuestionIds;
            } else {
                // 取交集
                questionIds.retainAll(categoryQuestionIds);
            }
            
            if (questionIds.isEmpty()) {
                return new PageResponse<>(0L, page, size, new ArrayList<>());
            }
        }
        
        // 构建分页对象
        Page<Question> pageParam = new Page<>(page, size);
        
        // 构建查询条件
        LambdaQueryWrapper<Question> queryWrapper = new LambdaQueryWrapper<>();
        
        // 添加ID筛选（如果有）
        if (!questionIds.isEmpty()) {
            queryWrapper.in(Question::getQuestionId, questionIds);
        }
        
        // 添加其他查询条件
        queryWrapper.like(StrUtil.isNotBlank(keyword), Question::getQuestionContent, keyword)
                    .eq(StrUtil.isNotBlank(category), Question::getCategory, category)
                    .eq(status != null, Question::getStatus, status)
                    .orderByDesc(Question::getCreateTime);
        
        // 执行分页查询
        IPage<Question> pageResult = questionMapper.selectPage(pageParam, queryWrapper);
        
        // 封装返回结果
        return new PageResponse<>(
                pageResult.getTotal(),
                (int) pageResult.getCurrent(),
                (int) pageResult.getSize(),
                pageResult.getRecords()
        );
    }
    
    @Override
    public Question getById(Long questionId) {
        Question question = questionMapper.selectById(questionId);
        if (question == null) {
            throw new BusinessException("问句不存在");
        }
        return question;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long create(Question question) {
        // 参数校验
        if (StrUtil.isBlank(question.getQuestionContent())) {
            throw new BusinessException("问句内容不能为空");
        }
        
        // 计算MD5值
        String content = question.getQuestionContent().trim();
        String md5 = DigestUtil.md5Hex(content);
        question.setContentMd5(md5);
        
        // 检查是否重复
        LambdaQueryWrapper<Question> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Question::getContentMd5, md5);
        Question existQuestion = questionMapper.selectOne(wrapper);
        
        if (existQuestion != null) {
            throw new BusinessException("该问句已存在，ID: " + existQuestion.getQuestionId());
        }
        
        // 设置默认值
        if (question.getStatus() == null) {
            question.setStatus(1);
        }
        if (question.getCollectCount() == null) {
            question.setCollectCount(0);
        }
        if (StrUtil.isBlank(question.getPriority())) {
            question.setPriority("medium");
        }
        
        question.setCreateTime(LocalDateTime.now());
        question.setUpdateTime(LocalDateTime.now());
        
        // 插入数据库
        questionMapper.insert(question);
        
        log.info("创建问句成功，ID: {}, MD5: {}", question.getQuestionId(), md5);
        return question.getQuestionId();
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(Question question) {
        // 检查问句是否存在
        Question existQuestion = questionMapper.selectById(question.getQuestionId());
        if (existQuestion == null) {
            throw new BusinessException("问句不存在");
        }
        
        // 参数校验
        if (StrUtil.isBlank(question.getQuestionContent())) {
            throw new BusinessException("问句内容不能为空");
        }
        
        // 重新计算MD5值
        String content = question.getQuestionContent().trim();
        String md5 = DigestUtil.md5Hex(content);
        question.setContentMd5(md5);
        
        // 检查是否与其他问句重复
        LambdaQueryWrapper<Question> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Question::getContentMd5, md5)
               .ne(Question::getQuestionId, question.getQuestionId());
        Question duplicate = questionMapper.selectOne(wrapper);
        
        if (duplicate != null) {
            throw new BusinessException("该问句内容已存在，ID: " + duplicate.getQuestionId());
        }
        
        question.setUpdateTime(LocalDateTime.now());
        
        // 更新数据库
        questionMapper.updateById(question);
        
        log.info("更新问句成功，ID: {}, MD5: {}", question.getQuestionId(), md5);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long questionId) {
        // 检查问句是否存在
        Question question = questionMapper.selectById(questionId);
        if (question == null) {
            throw new BusinessException("问句不存在");
        }
        
        // 删除问句
        questionMapper.deleteById(questionId);
        
        log.info("删除问句成功，ID: {}", questionId);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchDelete(List<Long> questionIds) {
        if (questionIds == null || questionIds.isEmpty()) {
            throw new BusinessException("请选择要删除的问句");
        }
        
        // 批量删除
        questionMapper.deleteBatchIds(questionIds);
        
        log.info("批量删除问句成功，数量: {}", questionIds.size());
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer batchImport(MultipartFile file) {
        if (file == null || file.isEmpty()) {
            throw new BusinessException("请上传文件");
        }
        
        try (InputStream inputStream = file.getInputStream()) {
            // 读取Excel文件
            ExcelReader reader = ExcelUtil.getReader(inputStream);
            
            // 读取数据（跳过标题行）
            List<Map<String, Object>> rows = reader.readAll();
            
            if (rows.isEmpty()) {
                throw new BusinessException("文件中没有数据");
            }
            
            List<Question> questions = new ArrayList<>();
            
            for (Map<String, Object> row : rows) {
                Question question = new Question();
                
                // 问句内容（必填）
                String content = row.get("问句内容") != null ? row.get("问句内容").toString() : null;
                if (StrUtil.isBlank(content)) {
                    continue; // 跳过空行
                }
                question.setQuestionContent(content.trim());
                
                // 问句类别
                String category = row.get("问句类别") != null ? row.get("问句类别").toString() : null;
                question.setCategory(StrUtil.isNotBlank(category) ? category.trim() : null);

                // 优先级
                String priority = row.get("优先级") != null ? row.get("优先级").toString() : "medium";
                question.setPriority(priority.trim());
                
                // 标签（逗号分隔）
                String tagsStr = row.get("标签") != null ? row.get("标签").toString() : null;
                if (StrUtil.isNotBlank(tagsStr)) {
                    List<String> tags = Arrays.stream(tagsStr.split("[,，]"))
                            .map(String::trim)
                            .filter(StrUtil::isNotBlank)
                            .collect(Collectors.toList());
                    question.setTags(tags);
                }
                
                // 备注
                String remark = row.get("备注") != null ? row.get("备注").toString() : null;
                question.setRemark(StrUtil.isNotBlank(remark) ? remark.trim() : null);
                
                // 设置默认值
                question.setStatus(1);
                question.setCollectCount(0);
                question.setCreateTime(LocalDateTime.now());
                question.setUpdateTime(LocalDateTime.now());
                
                questions.add(question);
            }
            
            if (questions.isEmpty()) {
                throw new BusinessException("没有有效的数据可导入");
            }
            
            // 批量插入
            questions.forEach(questionMapper::insert);
            
            log.info("批量导入问句成功，数量: {}", questions.size());
            return questions.size();
            
        } catch (Exception e) {
            log.error("批量导入问句失败", e);
            throw new BusinessException("批量导入失败：" + e.getMessage());
        }
    }
    
    @Override
    public List<String> getAllCategories() {
        LambdaQueryWrapper<Question> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(Question::getCategory)
                    .groupBy(Question::getCategory);
        
        List<Question> questions = questionMapper.selectList(queryWrapper);
        
        return questions.stream()
                .map(Question::getCategory)
                .filter(StrUtil::isNotBlank)
                .distinct()
                .collect(Collectors.toList());
    }
}

